perm filename MIXMON[MIX,SYS] blob sn#020791 filedate 1972-03-10 generic text, type T, neo UTF8
COMMENT ⊗   VALID 00012 PAGES 
RECORD PAGE   DESCRIPTION
 00001 00001
 00003 00002		MIXMON is the central interpreter for MIX instruction
 00006 00003	OPLST:	NOP
 00007 00004		Field specification:
 00008 00005		Memory specification:
 00010 00006		"Load" instructions.
 00012 00007		"Store" instructions.
 00015 00008		"Arithmetic" instructions.
 00020 00009		"Address transfer" insructions
 00022 00010		"Comparison" instructions.
 00024 00011		"Jump" instructions.
 00027 00012		Miscellaneous operators.
 00036 ENDMK
⊗;
COMMENT	⊗	MIXMON is the central interpreter for MIX instruction
		words.
	⊗

MIXMON:	SKIPN	UPD1
	JRST	.+3
	SOSN	UPD1
	UPDATE
	HLLZS	10, ERRORC		; check on too many errors
	TLNE	10, 200
	JRST	[OUTSTR [ASCIZ ⊗
#JOB HALTED, TOO MANY ERRORS#⊗]
		 JRST   HLT]
	INSKIP				; ANY INPUT FROM TTY → BACK TO BUTTON
	TLZE	FLAGS, SIFLAG		; SIFLAG → BACK TO BUTTON
	JRST	BUTTON			; RETURN CONTROL TO USER
	hrrz	10, pc			; is there a breakpoint at this address?
	movei	11, =19			; search thru table
	camn	10, bptab(11)		; is this it?
	jrst	[outstr	[asciz	/
#BREAKPOINT AT /]
		subi	10, mc0000	; make a relative address
		pushj	p, outd1
		outstr	[asciz /#
/]
		jrst	button]		; return to button mode
	sojge	11, .-2			; not this entry
MIXMN1:	HRRZ	10, PC			; PC>3999 → ERROR
	CAIL	10, MC0000
	CAILE	10, MC0000+(=3999)
	JRST	ZMOVER
	SUBI	10, MC0000		; save present value of PC
	MOVEM	10, ISPEC
	SETZM	JBUSX			; zero out JBUSX in case this is JBUS *
	MOVEM	10, MLOCK		; now test for Read-interlock
	RLOCK
	JRST	ZPCLOK			; error
	MOVE	INSTR, PC@		; GET INSTRUCTION WORD
	AOJ	PC,			; INCREMENT PROGRAM COUNTER
MIXMN2:	
	LDB	10,[POINT 6,INSTR,35]	;*RES* GET OP CODE
	SETZM	MSPEC			;ZERO OUT SAVED EFFECTIVE ADDRESS
	CAIE	10,5			;IS IT A SPECIAL INSTR WITH NO ADDRESS
	PUSHJ	P,MGET			; NO, GET EFECTIVE ADDRESS
	SKIPE	RUNC			; RUNC = 0 → no RUN file
	PUSHJ	P, DORUN
	AOS	EXTIME			; ONE MORE EXECUTE CYCLE
	MOVE	13, INSTR		; SET 13 TO OP-CODE
	ANDI	13, 77
	JRST	OPLST(13)@		; GO TO INSTRUCTION AREA

OPLST:	NOP
	0+ADD
	0+SUB
	0+MUL
	0+DIV
	SPEC
	SHIFTS
	0+MOVE

	LDA
	LD1
	LD2
	LD3
	LD4
	LD5
	LD6
	LDX

	LDAN
	LD1N
	LD2N
	LD3N
	LD4N
	LD5N
	LD6N
	LDXN

	STA
	ST1
	ST2
	ST3
	ST4
	ST5
	ST6
	STX

	STJ
	STZ
	JBUS
	IOC
	0+IN
	0+OUT
	JRED
	JUMPS

	JA
	J1
	J2
	J3
	J4
	J5
	J6
	JX

	MODA
	MOD1
	MOD2
	MOD3
	MOD4
	MOD5
	MOD6
	MODX

	CMPA
	CMP1
	CMP2
	CMP3
	CMP4
	CMP5
	CMP6
	CMPX

COMMENT	⊗	Field specification:
			if M is in register 12
			   F-byte is in register 11
		      then "FPOINT(11)" is a byte pointer
			   to the appropriate byte(s)
			   in the core position addressed
			   by M.  Sign byte not included.
			   0 → illegal F-byte.
	⊗

FPOINT:	44B5
	FOR Y←1,5
	 {POINT  Y*6, MC0000(12), Y*6+5
	 }
	REPEAT	2, {0}
	FOR X←1,5
	 {FOR Y←0,5
	   {IFGE  Y-X, THEN
	     {POINT  (Y-X+1)*6, MC0000(12), Y*6+5
	     }
	    IFL   Y-X, THEN
	     {0
	     }
	   }
	  REPEAT  2, {0}
	 }
	REPEAT	20, {0}
COMMENT	⊗	Memory specification:
			this subroutine assumes present instruction
		in INSTR and puts M into register 12--
	⊗

OPDEF	GETM	[PUSHJ	P,.]	


MGET:
	LDB	12, [POINT  6, INSTR, 23]	; GET INDEX-BYTE
	CAIL	12, 0				; INDEX<0 → ERROR
	CAILE	12, 6				; INDEX>6 → ERROR
	PUSHJ	P, YINDEX
	SKIPE	12				; INDEX=0 → NO INDEXING
	MOVE	12, (12)			; INDEX≠0 → GET INDEX REGISTER
	TLZE	12, 400000			; SIGN=0 → SKIP
	MOVNS	12				; SIGN=1 → NEGATE IT
	HLRZ	11, INSTR			; GET ADDRESS-BYTES
	TRZE	11, 400000			; SIGN=0 → SKIP
	MOVNS	11				; SIGN=1 → NEGATE IT
	ADD	12, 11				; M ← AA+(I)
	MOVEM	12, MSPEC			; save M
	POPJ	P,

OPDEF	GETF	[PUSHJ  P, .]
	LDB	11, [POINT  6, INSTR, 29]
	SKIPN	FPOINT(11)
	PUSHJ	P, YFIELD
	MOVEM	11, SAVEF
	POPJ	P,


OPDEF	TESTR	[PUSHJ  P, .]
	JUMPE	13, .+2
	CAILE	13, 6
	POPJ	P,
	TDZE	10, [XWD 7777,770000]
	JRST	YIREG
	POPJ	P,


OPDEF	TESTM	[PUSHJ P, .]
	CAIL	12, 0
	CAILE	12, =3999
	PUSHJ	P, YMOVER
	POPJ	P,

COMMENT	⊗	"Load" instructions.
	⊗

LDA:	LD1:	LD2:	LD3:	LD4:	LD5:	LD6:	LDX:
LDAN:	LD1N:	LD2N:	LD3N:	LD4N:	LD5N:	LD6N:	LDXN:

	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	TESTM
	MOVEM	12, MLOCK		; test for Read-interlock
	RLOCK
	JRST	ZRLOCK			; error
	GETF
	LDB	10, FPOINT(11)			; GET FIELD FROM MEMORY
	CAILE	11, 5				; F≤5 → GET SIGN
	JRST	.+3
	SKIPGE	MC0000(12)			; MC0000(12)≥0 → SIGN=+
	OR	10, [1B0]			; SIGN ← -
	CAILE	13, 17				; OP-CODE>15 → "LDN"
	TLC	10, 400000			; CHANGE SIGN
	ANDI	13, 7				; 13 ← REGISTER TO BE LOADED
	TESTR
	MOVEM	10, (13)			; LOAD REGISTER FROM 10
	AOS	EXTIME				; ONE MORE EXECUTE CYCLE
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER

COMMENT	⊗	"Store" instructions.
	⊗

STA:	ST1:	ST2:	ST3:	ST4:	ST5:	ST6:	STX:	

	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	TESTM
	MOVEM	12, MLOCK		; test for Write-interlock
	WLOCK
	JRST	ZWLOCK			; error
	GETF
	ANDI	13, 7				; 13 ← REGISTER TO BE STORED
	MOVE	10, (13)			; STORE REGISTER TO 10
	TESTR
	DPB	10, FPOINT(11)			; STORE FIELD INTO MEMORY
	CAILE	11, 5				; F≤5 → STORE SIGN-BYTE
	JRST	.+3
	LDB	10, [POINT  6, (13), 5]		; GET SIGN FROM REGISTER
	DPB	10, [POINT  6, MC0000(12), 5]	; STORE SIGN
	AOS	EXTIME				; ONE MORE EXECUTE CYCLE
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER


STJ:	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	TESTM
	MOVEM	12, MLOCK		; test for Write-interlock
	WLOCK
	JRST	ZWLOCK			; error
	GETF
	ANDI	13, 7				; 13 ← REGISTER TO BE STORED
	SETZ	10,				; CLEAR 10 IN PREPARATION
	DPB	RJ, FPOINT(11)			; STORE FIELD INTO MEMORY
	CAIG	11, 5				; F≤5 → STORE SIGN-BYTE
	DPB	10, [POINT  6, MC0000(12), 5]	; STORE SIGN
	AOS	EXTIME				; ONE MORE EXECUTE CYCLE
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER


STZ:	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	TESTM
	MOVEM	12, MLOCK		; test for Write-interlock
	WLOCK
	JRST	ZWLOCK			; error
	GETF
	ANDI	13, 7				; 13 ← REGISTER TO BE STORED
	SETZ	10,				; CLEAR 10 IN PREPARATION
	DPB	10, FPOINT(11)			; STORE FIELD INTO MEMORY
	CAIG	11, 5				; F≤5 → STORE SIGN-BYTE
	DPB	10, [POINT  6, MC0000(12), 5]	; STORE SIGN
	AOS	EXTIME				; ONE MORE EXECUTE CYCLE
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER
COMMENT	⊗	"Arithmetic" instructions.
	⊗

ADD:	SUB:	

	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	TESTM
	MOVEM	12, MLOCK			; test for Read-interlock
	RLOCK
	JRST	ZRLOCK				; error
	GETF
	LDB	10, FPOINT(11)			; GET FIELD FROM MEMORY
	CAILE	11, 5				; F≤5 → GET SIGN
	JRST	.+3
	SKIPGE	MC0000(12)			; MC0000(12)≥0 → SIGN=+
	MOVNS	10				; USE TWO'S COMPLEMENT FORM
	CAILE	13, 1				; OP-CODE≥1 → "SUB"
	MOVNS	10
	MOVE	11, RA				; SET UP 11 TO WORK
	TLZE	11, 400000			; SIGN≠0 → NEGATE 11
	MOVNS	11
	ADD	11, 10				; ADD
	JUMPGE	11, .+3				; 11≥0 → OK
	MOVNS	11				; 11<0 → FIX SIGN
	OR	11, [1B0]
	TLZE	11, 370000			; ANY OVERFLOW?
	TLO	FLAGS, OVFLAG			; YES → SET OVFLAG
	JUMPN	11, .+3				; 11=0 ∧ A<0 → CHANGE 11 TO -0
	JUMPGE	RA, .+2
	MOVE	11, [1B0]
	MOVE	RA, 11				; RESULTS TO REGISTER A
	AOS	EXTIME				; ONE MORE EXECUTE CYCLE
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER


MUL:	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	TESTM
	MOVEM	12, MLOCK			; test for Read-interlock
	RLOCK
	JRST	ZRLOCK				; error
	GETF
	LDB	10, FPOINT(11)			; GET FIELD FROM MEMORY
	CAILE	11, 5				; F≤5 → GET SIGN
	JRST	.+3				; USE +
	SKIPGE	MC0000(12)			; MC0000≥0 → SIGN=+
	TLOA	12, 400000			; SIGN=- → MAKE 12 NEGATIVE
	SETZ	12,				; SIGN=+ → MAKE 12 ZERO
	MOVE	11, RA				; SET UP 11 TO WORK
	TLZE	11, 400000			; SIGN=- → CHANGE SIGN OF 12
	TLC	12, 400000
	MUL	10, 11				; MULTIPLY
	LDB	RX, [POINT  30, 11, 35]		; NUMERIC BITS INTO RX, CLEAR SIGN
	ASHC	10, 5				; SHIFT SO RIGHT BITS IN 10
	LDB	RA, [POINT  30, 10, 35]		; NUMERIC BITS INTO RA, CLEAR SIGN
	JUMPGE	12, .+3				; 12≥0 → SIGN OF RESULT IS +
	TLO	RX, 400000			; SIGNS OF RX, RA ARE -
	TLO	RA, 400000
	MOVEI	10, 11				; NINE MORE EXECUTE CYCLES
	ADDM	10, EXTIME			
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER


DIV:	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	TESTM
	MOVEM	12, MLOCK			; test for Read-interlock
	RLOCK
	JRST	ZRLOCK				; error
	GETF
	LDB	13, FPOINT(11)			; GET FIELD FROM MEMORY
	SKIPGE	10, RA				; test sign of RA
	TLO	12, 600000			; reset sign bits in 12
	CAILE	11, 5				; F≤5 → use sign
	JRST	.+3
	SKIPGE	MC0000(12)			; if positive, no change
	TLC	12, 400000			; negative → change sign of RA
	CAML	10, 13				; |RA|≥|V| → OVERFLOW
	TLO	FLAGS, OVFLAG
	DPB	RX, [POINT  30, 11, 30]		; SET UP 11 FOR LOW-ORDER BITS
	ASHC	10, -5				; SHIFT INTO RIGHT POSITION FOR DIV
	DIV	10, 13				; DIVIDE
	TLNE	12, 400000			; CHECK QUOTIENT SIGN BIT
	TLO	10, 400000
	TLNE	12, 200000			; CHECK REMAINDER SIGN BIT
	TLO	11, 400000
	MOVE	RA, 10				; RA ← QUOTIENT
	MOVE	RX, 11				; RX ← REMAINDER
	MOVEI	10, 13				; ELEVEN MORE EXECUTE CYCLES
	ADDM	10, EXTIME
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER


COMMENT	⊗	"Address transfer" insructions
	⊗

MODA:	MOD1:	MOD2:	MOD3:	MOD4:	MOD5:	MOD6:	MODX:

	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	LDB	11, [POINT  6, INSTR, 29]
	MOVEM	11,SAVEF			;*RES* SAVE FOR TRACE ROUTINE 
	CAIG	11, 3
	SKIPGE	11
	PUSHJ	P, YFIELD		; ILLEGAL F-FIELD
	ANDI	13, 7				; 13 ← REGISTER TO BE MODIFIED
	MOVE	10, (13)			; 10 ← SET UP 10 TO WORK
	TLZE	10, 400000			; SIGN≠0 → NEGATE 10
	MOVNS	10				; USE TWO'S COMPLEMENT FORM
	XCT	MODXCT(11)			; PERFORM APPROPRIATE OPERATION
	JUMPGE	10, .+3				; 10≥0 → OK
	MOVNS	10				; 10<0 → FIX SIGN
	OR	10, [1B0]
	TLZE	10, 370000			; ANY OVERFLOW?
	TLO	FLAGS, OVFLAG			; YES → SET FLAG
	JUMPN	10, .+3				; SPECIAL CONDITIONS
	XCT	M0XCT(11)
	MOVE	10, [1B0]			;	→ CHANGE 10 TO -0
	TESTR
	MOVEM	10, (13)			; RESULTS TO REG
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER

MODXCT:	ADD	10, 12			; F=0 → INC...
	SUB	10, 12			; F=1 → DEC...
	MOVE	10, 12			; F=2 → ENT...
	MOVN	10, 12			; F=3 → ENN...

M0XCT:	SKIPGE	(13)			; F=0 → USE SIGN OF REG
	SKIPGE	(13)			; F=1 → USE SIGN OF REG
	SKIPGE	INSTR			; F=2 → USE SIGN OF INSTR
	SKIPGE	INSTR			; F=3 → USE SIGN OF INSTR

COMMENT	⊗	"Comparison" instructions.
	⊗

CMPA:	CMP1:	CMP2:	CMP3:	CMP4:	CMP5:	CMP6:	CMPX:

	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	TESTM
	MOVEM	12, MLOCK			; test for Read-interlock
	RLOCK
	JRST	ZRLOCK				; error
	GETF
	LDB	10, FPOINT(11)			; GET FIELD FROM MEMORY
	CAILE	11, 5				; F≤5 → GET SIGN
	JRST	.+3
	SKIPGE	MC0000(12)			; MC0000(12)≥0 → SIGN=+
	MOVNS	10				; USE TWO'S COMPLEMENT FORM
	ANDI	13, 7				; 13 ← REGISTER TO COMPARE
	MOVE	12, FPOINT(11)			; PUT FIELD-BYTE POINTER INTO 12
	TDC	12, [1000000+MC0000]		; POINTER ADDRESS ← "(13)"
COMMENT ⊗ THIS (↑) CLEVERNESS IS DUE TO DAN SWINEHART ⊗
	LDB	12, 12				; GET FIELD FROM REGISTER SHOWN IN 13
	CAILE	11, 5				; F≤5 → GET SIGN
	JRST	.+3
	SKIPGE	(13)				; (13)≥0 → SIGN=+
	MOVNS	12
	SUB	12, 10				; SUBTRACT TO GET COMPARE RESULT
	TLZ	FLAGS, GFLAG∨EFLAG∨LFLAG	; ZERO COMPARISON FLAGS
	JUMPLE	12, .+3				; ≤ → MOVE ON
	TLO	FLAGS, GFLAG			; > → SET FLAG
	JRST	.+4				; DONE
	JUMPL	12, .+2				; < → MOVE ON
	TLOA	FLAGS, EFLAG			; = → SET FLAG, SKIP
	TLO	FLAGS, LFLAG			; < → SET FLAG
	AOS	EXTIME				; ONE MORE EXECUTE CYCLE
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER

COMMENT	⊗	"Jump" instructions.
	⊗

JUMPS:	MOVE	12,MSPEC
	TESTM
	LDB	11, [POINT  6, INSTR, 29]	; GET FIELD-BYTE
	MOVEM	11, SAVEF
	CAILE	11, 11				; F>9 → ERROR
	PUSHJ	P, Y2FIEL
	MOVE	11, SAVEF
	XCT	JMPXCT(11)			; PERFORM APPROPRIATE TEST
	JRST	MIXMON				; THERE WILL BE NO JUMP
JMP:	HRRZ	RJ, PC				; RJ ← PC-MC0000
	SUBI	RJ, MC0000
JSJ:	JUMPL	12, ZMOVER			; 12<0 → ERROR
						;	(12>3999 WILL BE FOUND LATER)
	ADDI	12, MC0000			; PC ← M+MC0000
	HRR	PC, 12
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER

JMPXCT:	JRST	JMP			; F=0 → JMP
	JRST	JSJ			; F=1 → JSJ
	TLZN	FLAGS, OVFLAG		; F=2 → JOV
	TLZE	FLAGS, OVFLAG		; F=3 → JNOV
	TLNN	FLAGS, LFLAG		; F=4 → JL
	TLNN	FLAGS, EFLAG		; F=5 → JE
	TLNN	FLAGS, GFLAG		; F=6 → JG
	TLNN	FLAGS, GFLAG∨EFLAG	; F=7 → JGE
	TLNN	FLAGS, GFLAG∨LFLAG	; F=8 → JNE
	TLNN	FLAGS, LFLAG∨EFLAG	; F=9 → JLE


JA:	J1:	J2:	J3:	J4:	J5:	J6:	JX:

	MOVE	12,MSPEC
	TESTM
	LDB	11, [POINT  6, INSTR, 29]	; GET FIELD-BYTE
	MOVEM	11, SAVEF
	CAILE	11, 7				; F>7 → ERROR
	PUSHJ	P, Y2FIEL
	MOVE	11, SAVEF
	ANDI	13, 7				; 13 ← REGISTER TO TEST
	MOVE	10, (13)			; SET UP 10 TO WORK
	TLC	10, 400000			; CHECK FOR -0
	JUMPE	10, .+2				; NOT -0 SO RECOMPLEMENT
	TLC	10, 400000
	XCT	JXCT(11)			; TO MIXMON IF TEST FAILS
	JRST	JMP				; PERFORM THE JUMP
	JRST	MIXMON

JXCT:	JUMPGE	10, MIXMON		; F=0 → J.N
	JUMPN	10, MIXMON		; F=1 → J.Z
	JUMPLE	10, MIXMON		; F=2 → J.P
	JUMPL	10, MIXMON		; F=3 → J.NN
	JUMPE	10, MIXMON		; F=4 → J.NZ
	JUMPG	10, MIXMON		; F=5 → J.NP
	TRNN	10, 1			; F=6 → J.E
	TRNE	10, 1			; F=7 → J.O

COMMENT	⊗	Miscellaneous operators.
	⊗

MOVE:	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	TESTM
	LDB	11, [POINT  6, INSTR, 29]	; GET FIELD-BYTE
	MOVEM	11, SAVEF
	JUMPE	11, MIXMON			; F=0 → LIKE A NOP
	HRLM	12, MLOCK			; test for read-interlock-range
	HRRM	12, MLOCK
	ADDM	11, MLOCK
	RRLOCK
	JRST	ZRLOCK
	MOVE	11,SAVEF		;*RES* RRLOCK CLOBBERS 11
	HRLM	R1, MLOCK			; test for write-interlock-range
	HRRM	R1, MLOCK
	ADDM	11, MLOCK
	WWLOCK
	JRST	ZWLOCK
	MOVE	11,SAVEF		;*RES* WWLOCK CLOBBERS 11
	MOVE	10, R1				; COMPUTE ADDRESS OF
	ADD	10, 11				;     FINAL DESTINATION
	SUBI	10, 1
	JUMPL	10, ZMOVER			; 10<0 → ERROR
	CAILE	10, =3999			; 10>3999 → ERROR
	JRST	ZMOVER
	JUMPL	R1, ZMOVER			; R1<0 → ERROR
	MOVE	13, R1				; 13 WILL HOLD BLT POINTER
	HRL	13, 12				; SOURCE ADDRESS IS M
	ADD	13, [XWD  MC0000, MC0000]	; RELOCATION (SORT OF)
	BLT	13, MC0000(10)			; PERFORM MOVE OPERATION
	ADD	R1, 11				; R1 ← R1+F
	LSH	11, 1				; 2*F MORE EXECUTE CYCLES
	ADDM	11, EXTIME
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER


SHIFTS:	LDB	13, [POINT  6, INSTR, 29]	; GET FIELD-BYTE
	MOVEM	13, SAVEF
	CAIL	13, 0				; F<0 → ERROR
	CAILE	13, 7				; F>7 → ERROR
	PUSHJ	P, Y2FIEL
	MOVE	13, SAVEF
	MOVE	12,MSPEC			; GET MEMORY SPECIFICATION
	JUMPL	12, ZMOVER			; 12<0 → ERROR
	TRNE	13, 1				; 13 ODD → SHIFT RIGHT
	MOVNS	12				;     SO NEGATE FACTOR
	IMULI	12, 6				; 1 BYTE = 6 BITS
	CAILE	13, 1				; F=0,1 → SLA,SRA
	JRST	SAX
	MOVE	10, RA				; SET UP 10 TO WORK
	TLZ	10, 400000			; IGNORE SIGN
	LSH	10, (12)			; PERFORM SHIFT
	DPB	10, [POINT  30, RA, 35]		; PUT BACK SHIFTED BYTES
	AOS	EXTIME				; ONE MORE EXECUTE CYCLE
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER

SAX:	MOVE	10, RA				; SET UP 10, 11 TO WORK
	MOVE	11, RX
	TLZ	10, 400000			; IGNORE SIGN
	LSH	11, 6				; CONCATENATE MEANINGFUL BYTES
	CAIGE	13, 6				; F=6,7 → SRB,SLB
	JRST	.+3				; OTHERWISE
	IDIVI	12, 6				; SO CHANGE BACK TO BITS
	JRST	.+3
	CAILE	13, 3				; F=2,3 → SLAX,SRAX
	JRST	SC
	LSHC	10, (12)			; PERFORM SHIFT
	LSH	11, -6				; BYTES TO NORMAL POSITIONS
	DPB	10, [POINT  30, RA, 35]		; PUT BACK SHIFTED BYTES
	DPB	11, [POINT  30, RX, 35]
	AOS	EXTIME				; ONE MORE EXECUTE CYCLE
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER

SC:	ADDI	12, =30000			; MAKE 12>0 SO CAN USE
	IDIVI	12, =60				;     MOD(10)
	ROTC	10, (13)			; PERFORM SHIFT
	HRRZ	12, 13				; 6 BITS = 1 BYTE
	IDIVI	12, 6
	HRR	RX, 12				; USE RX FOR INDEXING
	MOVE	12, 10				; 12,13 USED TO SAVE BYTES
	MOVE	13, 11				;     WHICH ARE CORRECT
	AND	12, ROTA(RX)
	AND	13, ROTX(RX)
	ROTC	10, 14				; ROTATE TO GET REST OF GOOD BYTES
	ANDCM	10, ROTA(RX)			; MASK OUT BAD BYTES
	ANDCM	11, ROTX(RX)
	OR	10, 12				; PUT GOOD PARTS TOGETHER
	OR	11, 13
	LSH	11, -6				; BYTES TO NORMAL POSITIONS
	DPB	10, [POINT  30, RA, 35]		; PUT BACK SHIFTED BYTES
	DPB	11, [POINT  30, RX, 35]
	AOS	EXTIME				; ONE MORE EXECUTE CYCLE
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER

ROTA:	XWD  7777,777777			; MASKING TABLES FOR SLC AND SRC
	XWD  7777,777777
	XWD  7777,777777
	XWD  7777,777777
	XWD  7777,777777
	XWD  7777,777777
	XWD  7777,777700
	XWD  7777,770000
	XWD  7777,000000
	XWD  7700,000000
ROTX:	XWD  777777,777700
	XWD  777777,770000
	XWD  777777,000000
	XWD  777700,000000
	XWD  770000,000000
	XWD  000000,000000
	XWD  000000,000000
	XWD  000000,000000
	XWD  000000,000000
	XWD  000000,000000


NOP:	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER


SPEC:	LDB	12, [POINT  6, INSTR, 29]	; GET FIELD-BYTE
	MOVEM	12, SAVEF
	CAIL	12, 0
	CAILE	12, 2
	PUSHJ	P, Y2FIEL
	MOVE	12, SAVEF
	CAIE	12, 2				; F=2 → HLT
	JRST	.+5
HLT:	OUTSTR	[ASCIZ  ⊗
#HALT#⊗]
	SKIPE	RUNC				; RUNC=0 → NO RUN FILE
	JRST	ENDRUN
	JRST	BUTTON				; RETURN CONTROL TO USER
	JUMPN	12, CHAR			; F>0 → CHAR
NUM:	SETZ	12,				; CLEAR 12 TO ACCUMULATE RESULT
	HRRI	13, 0				; INITIALIZE POINTER ADDRESS
	HRLI	13, 360600			; INITIALIZE BYTE INDICATORS
	ILDB	10, 13				; GET CHARACTER
	IDIVI	10, 12				; GET MOD(10)
	IMULI	12, 12				; ACCUMULATE SUM
	ADD	12, 11
	TLNE	13, 770000			; FINISHED WITH BATCH OF 5 BYTES?
	JRST	.-5				; NO → GET SOME MORE
	TRON	13, 7				; WAS THIS RX?
	JRST	.-10				; NO, BUT NOW IT IS!!!
	TLZE	12, 370000			; DONE → TEST FOR OVERFLOWS
	TLO	FLAGS, OVFLAG			; YES → SET FLAG
	DPB	12, [POINT  30, RA, 35]		; PUT NUM INTO RA
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER
CHAR:	MOVE	10, RA				; INITIALIZE 10
	TLZ	10, 400000			; IGNORE SIGN
	MOVEI	13, 1				; LOOP COUNTER
	SETZ	12,				; ZERO OUT WORK REGISTER
	IDIVI	10, 12				; GET REMAINDER
	ADDI	11, 36				; CONVERT TO CHARACTER CODE
	OR	12, 11				; PUT CHAR INTO WORK REGISTER
	ROT	12, -6				; SHIFT RIGHT ONE BYTE
	TRNN	12, 7700			; TEST FOR 5 BYTES
	JRST	.-5				; NO → GET MORE
	LSH	12, -6				; PUT INTO RIGHT POSITION
	DPB	12, CPOINT(13)			; PUT INTO RX OR RA
	SOJGE	13, .-11			; ONE MORE TIME?
	JRST	MIXMON				; RETURN TO INSTRUCTION INTERPRETER
CPOINT:	POINT	30, RA, 35
	POINT	30, RX, 35

PATCH:	BLOCK	=100			;*RES*